//
// @Auther: by wujehy 
// @Email:wujehy@qq.com
// @Data:2020/9/11
// @Time:1:46 下午
//
//

#include <iostream>
#include "AppManager.h"
#include "glog/logging.h"
#include "NetWork/NetworkManager.h"
#include "ThreadPool.h"
#include "base_types.h"
#include "ModManager.h"

using namespace GeeJoan;

void AppManager::init_local()
{

    if (init_before_callback)init_before_callback(this);

    FLAGS_log_dir = m_logPath;
    google::InitGoogleLogging( "MainServer" );
    google::SetStderrLogging( google::GLOG_INFO );
//    google::SetStderrLogging(google::GLOG_WARNING);

//    google::ShutdownGoogleLogging();
    modManager->init();
    if (init_after_callback)init_after_callback(this);

}

AppManager::AppManager()
{
    m_mutex.lock();
    if (m_threadPool == nullptr)
    {
        m_threadPool = new ThreadPool( 2 );
        m_threadPool->start();
    }

    if (globalContext == nullptr)
    {
        globalContext = new Global_Context;
    }
    if (modManager == nullptr)
    {
        modManager = new ModManager;
    }
    if (this->m_io_context == nullptr)
    {
        boost::asio::io_context *io_context = new boost::asio::io_context;
        this->m_io_context = io_context;
    }
    m_mutex.unlock();
}

AppManager::~AppManager()
{
    if (delete_before_callback)delete_before_callback(this);
    LOGINFO << " ~AppManager start ";
    this->stop();
    m_mutex.lock();
    if (networkManager != nullptr)
    {
        delete networkManager;
    }

    if (this->m_io_context != nullptr)
    {
        boost::asio::io_context *io_context = (boost::asio::io_context *) this->m_io_context;
        delete io_context;
    }

    if (m_threadPool != nullptr)
    {
        m_threadPool->stop();
        delete m_threadPool;
    }

    if (modManager != nullptr)
    {
        delete modManager;
    }
    if (globalContext != nullptr)
    {
        delete globalContext;
    }
    m_mutex.unlock();

    google::ShutdownGoogleLogging();
    if (delete_after_callback)delete_after_callback(this);

}

int AppManager::init_network()
{
    m_mutex.lock();
    if (this->m_io_context != nullptr)
    {
        boost::asio::io_context *io_context = (boost::asio::io_context *) this->m_io_context;
        this->networkManager = new NetworkManager( *io_context, port );

    }
    m_mutex.unlock();

    // 统一初始化

    networkManager->init();
    this->networkManager->start();


    this->call_init_success();
    return 0;
}

int AppManager::call_init_success()
{
    if (init_success_before_callback)init_success_before_callback(this);
    globalContext->networkManager = networkManager;
    globalContext->appManager = this;
    globalContext->threadPool = m_threadPool;
    globalContext->modManager = modManager;
    modManager->init_complete( globalContext );
    networkManager->init_complete( globalContext );
    if (init_success_before_callback)init_success_before_callback(this);
    return 0;
}

void AppManager::run()
{
    boost::asio::io_context *io_context = (boost::asio::io_context *) this->m_io_context;
    LOG( INFO ) << " io_context->stopped() " << io_context->stopped();

    LOG( INFO ) << " do run ";
    io_context->run();

}

void AppManager::stop()
{
    boost::asio::io_context *io_context = (boost::asio::io_context *) this->m_io_context;
//    if (!io_context->stopped())
//    {
    io_context->stop();

//    }
}

void AppManager::setLogPath(const std::string &mLogPath)
{
    m_logPath = mLogPath;
}

void AppManager::setPort(int port)
{
    AppManager::port = port;
}

bool AppManager::registerModFunc(BaseMod *mod, bool auto_del)
{
    return modManager->registerModFunc(mod , auto_del);
}
